package biz.datalk.industrialland.admin.modules.online.config.util;

import biz.datalk.industrialland.admin.modules.online.dynform.pojo.po.DynformButton;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * 按钮工具类
 *
 * @author tarofang@163.com
 * @date 2020-01-09
 *
 */
public class DynfromButtonUtil {
    /** 添加按钮 */
    public static final String DEFAULT_ADD_BTN_CODE = "default_btn_add";
    /** 编辑按钮 */
    public static final String DEFAULT_EDIT_BTN_CODE = "default_link_edit";
    /** 详细按钮 */
    public static final String DEFAULT_DETAIL_BTN_CODE = "default_link_detail";
    /** 删除按钮 */
    public static final String DEFAULT_DELETE_BTN_CODE = "default_link_delete";

    public static final String DEFAULT_ALL_BTN_CODE = "default_btn_add,default_link_edit,default_link_delete,default_link_detail";

    public static final String BTN_STYLE_LINK = "link";
    public static final String BTN_STYLE_BUTTON = "button";
    public static final String BTN_DATALK_OVERRIDE = "datalk_override";

    public static boolean hasDefaultBtn(List<DynformButton> btns) {
        if (CollectionUtils.isEmpty(btns)) {
            return false;
        }

        for (DynformButton btn : btns) {
            if (isDefaultBtn(btn)) {
                return true;
            }
        }

        return false;
    }

    public static boolean isDefaultBtn(DynformButton btn) {
        if (btn == null) {
            return false;
        }
        return isDefaultBtn(btn.getBtnCode());
    }

    public static boolean isDefaultBtn(String btnCode) {
        return StringUtils.equalsAny(StringUtils.trimToEmpty(btnCode), DEFAULT_ADD_BTN_CODE, DEFAULT_EDIT_BTN_CODE, DEFAULT_DETAIL_BTN_CODE, DEFAULT_DELETE_BTN_CODE);
    }

    public static DynformButton getDefaultBtn(String defaultBtnCode, String tableId) {
        if (!StringUtils.equalsAny(StringUtils.trimToEmpty(defaultBtnCode), DEFAULT_ADD_BTN_CODE, DEFAULT_EDIT_BTN_CODE, DEFAULT_DETAIL_BTN_CODE, DEFAULT_DELETE_BTN_CODE)) {
            throw new IllegalArgumentException("Invalid default button code: " + defaultBtnCode);
        }

        defaultBtnCode = StringUtils.trimToEmpty(defaultBtnCode);
        DynformButton button = new DynformButton();
        if (StringUtils.equals(defaultBtnCode, DEFAULT_ADD_BTN_CODE)) {
            return button.setBtnIcon("el-icon-plus").setBtnCode(DEFAULT_ADD_BTN_CODE).setBtnName("添加").setBtnOrder(-3).setTableId(tableId);
        }

        if (StringUtils.equals(defaultBtnCode, DEFAULT_EDIT_BTN_CODE)) {
            return button.setBtnIcon("").setBtnCode(DEFAULT_EDIT_BTN_CODE).setBtnName("编辑").setBtnOrder(-3).setTableId(tableId);
        }

        if (StringUtils.equals(defaultBtnCode, DEFAULT_DETAIL_BTN_CODE)) {
            return button.setBtnIcon("").setBtnCode(DEFAULT_DETAIL_BTN_CODE).setBtnName("详情").setBtnOrder(-2).setTableId(tableId);
        }

        return button.setBtnIcon("").setBtnCode(DEFAULT_DELETE_BTN_CODE).setBtnName("删除").setBtnOrder(-1).setTableId(tableId);
    }

    public static Map<String, List<DynformButton>> getDefaultBtns(String tableDefBtns, String tableId) {
        String[] defBtnCodeArr = new String[0];
        if (StringUtils.isNotBlank(tableDefBtns)) {
            defBtnCodeArr = biz.datalk.commons.utils.StringUtils.splitAndTrim(tableDefBtns, ",");
        }

        List<DynformButton> defButtonBtns = new ArrayList<>();
        List<DynformButton> defLinkBtns = new ArrayList<>();
        for (String defBtnCode : defBtnCodeArr) {
            if (StringUtils.equals(defBtnCode, DEFAULT_ADD_BTN_CODE)) {
                defButtonBtns.add(getDefaultBtn(DEFAULT_ADD_BTN_CODE, tableId));
            }
            if (StringUtils.equals(defBtnCode, DEFAULT_EDIT_BTN_CODE)) {
                defLinkBtns.add(getDefaultBtn(DEFAULT_EDIT_BTN_CODE, tableId));
            }
            if (StringUtils.equals(defBtnCode, DEFAULT_DETAIL_BTN_CODE)) {
                defLinkBtns.add(getDefaultBtn(DEFAULT_DETAIL_BTN_CODE, tableId));
            }
            if (StringUtils.equals(defBtnCode, DEFAULT_DELETE_BTN_CODE)) {
                defLinkBtns.add(getDefaultBtn(DEFAULT_DELETE_BTN_CODE, tableId));
            }
        }

        // btnOrder 升序
        if (defButtonBtns.size() > 1) {
            defButtonBtns.sort(Comparator.comparing(DynformButton::getBtnOrder));
        }
        if (defLinkBtns.size() > 1) {
            defLinkBtns.sort(Comparator.comparing(DynformButton::getBtnOrder));
        }

        Map<String, List<DynformButton>> resMap = new HashMap<>(4);
        resMap.put(BTN_STYLE_BUTTON, defButtonBtns);
        resMap.put(BTN_STYLE_LINK, defLinkBtns);
        return resMap;
    }

    public static Map<String, List<DynformButton>> packageUseBtns(List<DynformButton> btns, String tableDefBtns, String tableId) {
        btns = CollectionUtils.isEmpty(btns) ? new ArrayList<>() : btns;

        Map<String, List<DynformButton>> defaultBtnsMap = getDefaultBtns(tableDefBtns, tableId);
        List<DynformButton> defButtonBtns = defaultBtnsMap.get(BTN_STYLE_BUTTON);
        List<DynformButton> defLinkBtns = defaultBtnsMap.get(BTN_STYLE_LINK);

        List<DynformButton> buttonBtns = new ArrayList<>();
        List<DynformButton> linkBtns = new ArrayList<>();

        Map<String, List<DynformButton>> resMap = new HashMap<>(4);
        resMap.put(BTN_STYLE_BUTTON, buttonBtns);
        resMap.put(BTN_STYLE_LINK, linkBtns);

        /* 无覆盖默认按钮情况 */
        if (!hasDefaultBtn(btns)) {
            buttonBtns.addAll(defButtonBtns);
            linkBtns.addAll(defLinkBtns);

            // 按钮所属位置区分
            String btnStyle;
            for (DynformButton btn : btns) {
                btnStyle = StringUtils.trimToEmpty(btn.getBtnStyle());
                if (StringUtils.equals(btnStyle, BTN_STYLE_LINK)) {
                    linkBtns.add(btn);
                }
                if (StringUtils.equals(btnStyle, BTN_STYLE_BUTTON)) {
                    buttonBtns.add(btn);
                }
            }
            return resMap;
        }

        //============================================================================================================

        /* 有覆盖默认按钮情况 */
        // 分离被覆盖的默认按钮与自定义按钮，并修正被覆盖的默认按钮的位置
        List<DynformButton> coveredDefaultButtonBtns = new ArrayList<>();
        List<DynformButton> coveredDefaultLinkBtns = new ArrayList<>();
        btnSeparate(btns, buttonBtns, linkBtns, coveredDefaultButtonBtns, coveredDefaultLinkBtns);


        // 按钮区 被覆盖的的默认按钮处理
        handleBtn(defButtonBtns, buttonBtns, coveredDefaultButtonBtns);

        // 列表区 被覆盖的的默认按钮处理
        handleBtn(defLinkBtns, linkBtns, coveredDefaultLinkBtns);

        return resMap;
    }

    /**
     * 处理按钮区域(列表上方)的按钮
     * 处理列表区域(列表中操作列)的按钮
     *
     * @param defBtns 默认按钮
     * @param customBtns 自定义按钮
     * @param coveredDefBtns 被覆盖的默认按钮
     */
    private static void handleBtn(List<DynformButton> defBtns, List<DynformButton> customBtns, List<DynformButton> coveredDefBtns) {
        /* 默认按钮 没有被覆盖 */
        if (CollectionUtils.isEmpty(coveredDefBtns)) {
            // 有默认按钮
            if (CollectionUtils.isNotEmpty(defBtns)) {
                defBtns.addAll(customBtns);
                customBtns.clear();
                customBtns.addAll(defBtns);
            }
            return;
        }

        /* 默认按钮 被覆盖 */
        // 修正按钮为覆盖，并获取覆盖的按钮编码
        List<String> converedBtnCodes = new ArrayList<>();
        for (DynformButton converedBtn : coveredDefBtns) {
            converedBtn.setBtnStyle(BTN_DATALK_OVERRIDE);
            converedBtnCodes.add(converedBtn.getBtnCode());
        }

        // 从默认按钮中排除被覆盖的按钮
        defBtns.removeIf(next -> converedBtnCodes.contains(next.getBtnCode()));

        defBtns.addAll(coveredDefBtns);
        // 默认按钮排序  升序
        for (DynformButton defBtn : defBtns) {
            switch (defBtn.getBtnCode()) {
                case DEFAULT_EDIT_BTN_CODE:
                    defBtn.setBtnOrder(-3);
                    break;
                case DEFAULT_DETAIL_BTN_CODE:
                    defBtn.setBtnOrder(-2);
                    break;
                case DEFAULT_DELETE_BTN_CODE:
                    defBtn.setBtnOrder(-1);
                    break;
                case DEFAULT_ADD_BTN_CODE:
                    defBtn.setBtnOrder(-3);
                    break;
                default:
                    defBtn.setBtnOrder(0);
                    break;
            }
        }
        defBtns.sort(Comparator.comparing(DynformButton::getBtnOrder));

        defBtns.addAll(customBtns);
        customBtns.clear();
        customBtns.addAll(defBtns);
    }

    /**
     * 分离被覆盖的默认按钮与自定义按钮，并修正被覆盖的默认按钮的位置
     *
     * @param btns 所有自定义按钮(包含被覆盖的默认按钮)
     * @param buttonBtns 按钮区的按钮
     * @param linkBtns 列表区的按钮
     * @param coveredDefaultButtonBtns 被覆盖的按钮区的默认按钮
     * @param coveredDefaultLinkBtns 被覆盖的列表区的默认按钮
     */
    private static void btnSeparate(List<DynformButton> btns, List<DynformButton> buttonBtns, List<DynformButton> linkBtns, List<DynformButton> coveredDefaultButtonBtns, List<DynformButton> coveredDefaultLinkBtns) {
        String btnCode, btnStyle;
        for (DynformButton btn : btns) {
            btnCode = StringUtils.trimToEmpty(btn.getBtnCode());
            if (StringUtils.equals(btnCode, DEFAULT_ADD_BTN_CODE)) {
                coveredDefaultButtonBtns.add(btn);
                continue;
            }
            if (StringUtils.equalsAny(btnCode, DEFAULT_EDIT_BTN_CODE, DEFAULT_DETAIL_BTN_CODE, DEFAULT_DELETE_BTN_CODE)) {
                coveredDefaultLinkBtns.add(btn);
                continue;
            }
            btnStyle = StringUtils.trimToEmpty(btn.getBtnStyle());
            if (StringUtils.equals(btnStyle, BTN_STYLE_LINK)) {
                linkBtns.add(btn);
            }
            if (StringUtils.equals(btnStyle, BTN_STYLE_BUTTON)) {
                buttonBtns.add(btn);
            }
        }
    }


    public static void main(String[] args) {
        String x = "default_btn_add , default_link_edit ,default_link_delete,default_link_detail ";
        List<DynformButton> btns = new ArrayList<>();
        for (int idx = 0; idx < 10; idx ++) {
            String id = "id_".concat(String.valueOf(idx));
            String btnCode = "btnCode".concat(String.valueOf(idx));
            String style = idx % 2 == 0 ? BTN_STYLE_BUTTON : BTN_STYLE_LINK;

            if (idx == 4) {
                btnCode = DEFAULT_DELETE_BTN_CODE;
            }

            if (idx == 5) {
                btnCode = DEFAULT_EDIT_BTN_CODE;
            }

            btns.add(new DynformButton().setId(id).setBtnCode(btnCode).setBtnOrder(idx + 1).setBtnStyle(style));
        }

        Map<String, List<DynformButton>> stringListMap = packageUseBtns(btns,x, "xxx");
        System.out.println(stringListMap);

        // String x = "default_btn_add , default_link_edit ,default_link_delete,default_link_detail ";
        // String[] defBtnCodeArr = StringUtils.splitPreserveAllTokens(x, ",");

        // System.out.println(defBtnCodeArr);
    }
}
